/**
 * Created by IntelliJ IDEA.
 * User: tkurz
 * Date: 25.01.12
 * Time: 08:53
 * To change this template use File | Settings | File Templates.
 */
(function( $ ) {
  $.fn.concepts = function(url) {

      var self = $(this);

      var model = [];

      //sparql
      var endpoint = "http://localhost:8080/connectme/sparql/select";
      var type = "application/sparql-results+json";
      var query =   "SELECT ?fragment ?resource  WHERE {"+
                    "   <"+url+"> <http://www.w3.org/ns/ma-ont#hasFragment> ?fragment."+
                    "   ?a <http://www.openannotation.org/ns/hasTarget> ?fragment."+
                    "   ?a <http://www.openannotation.org/ns/hasBody> ?resource."+
                    "}";

      //ldpath
      var ldpath_service = "http://localhost:8080/connectme/cmf/service/templating/resource";
      var template =  "<div style='border: 1px solid black;padding:5px;margin-bottom:5px;'>" +
                        "   <h3>{<http://www.w3.org/2000/01/rdf-schema#label>[@en]::xsd:string}</h3>" +
                        "   <p>{<http://dbpedia.org/ontology/abstract>[@en]::xsd:string}</p>" +
                        "   <a href='{<http://xmlns.com/foaf/0.1/page>::xsd:anyURI}' style='font-size:12;color:red' target='_blank'>more</a>" +
                        "</div>";

      function sparql(endpoint,query,callback) {
        $.getJSON(endpoint+"?query="+encodeURIComponent(query)+"&output="+encodeURIComponent(type),callback);
      }

      function createModel(data) {
          var list = data.results.bindings;
          for(var i=0; i<list.length;i++) {
              var item = {active:false};
              item.target = new URI(list[i].fragment.value);
              item.body = list[i].resource.value;
              model.push(item);
          }
      }

      /**
       * Internal model for a uri + fragment
       * @param http_url
       */
      function URI(http_url) {
            var hash = undefined;
            http_url = decodeURIComponent(http_url);
            var split = http_url.split("#", 2);
            var src = split[0];

            function parseTime(time_string) {
                var time = {};
                if (time_string.indexOf(",") > -1) {
                    var time_array = time_string.split(",", 2);
                    if (time_array[0] == "")time.start = 0;
                    else time.start = parseFloat(time_array[0]);
                    time.end = parseFloat(time_array[1]);
                } else {
                    time.start = parseFloat(time_string);
                    time.end = 4294967295; //MAX value
                }
                return time;
            }

            function parseRegion(region_string) {
                var region = {};
                var region_array = region_string.split(",", 4);
                region.x = parseInt(region_array[0]);
                region.y = parseInt(region_array[1]);
                region.w = parseInt(region_array[2]);
                region.h = parseInt(region_array[3]);
                return region;

            }

            function append(part) {
                var name_val = part.split("=");
                switch (name_val[0]) {
                    case 't':
                        hash.time = parseTime(name_val[1]);
                        break;
                    case 'xywh':
                        hash.region = parseRegion(name_val[1]);
                        break;
                }
            }

            if (split.length > 1) {
                hash = {};
                var hash_string = split[1];
                var parts = hash_string.split("&");
                for (var i = 0; i < parts.length; i++) {
                    append(parts[i]);
                }
            }

            this.getSrc = function() {
                return src
            };
            this.getFragment = function() {
                return hash
            };
            this.hasFragment = function() {
                return hash != undefined;
            };
            this.hasTimeFragment = function() {
                return (hash != undefined) ? hash.time != undefined : false;
            }
            this.hasRegionFragment = function() {
                return (hash != undefined) ? hash.region != undefined : false;
            }
            this.encloseTime = function(time) {
                return this.hasTimeFragment() ? hash.time.start<time&&time<hash.time.end : false;
            }

            this.encloseRegion = function(point) {
                return //TODO this.hasRegionFragment() ? hash.region.x;
            }
      }

      function show(item) {
          if(item.active) return;
          item.active=true;

          var elem = $("<div></div>");
          item.elem = elem;
          elem.load(ldpath_service+"?uri="+encodeURIComponent(item.body)+"&template="+encodeURIComponent(template),function(){
            self.append(elem);
          });
      }

      function hide(item) {
          if(!item.active) return;
          item.active=false;
          item.elem.remove();
          item.elem=undefined;
      }

      sparql(endpoint,query,createModel);

      function onTimeUpdateEvent(e) {
          for(var i=0; i<model.length; i++) {
              var item = model[i];
              if(item.target.encloseTime(e.currentTime)){
                show(item);
              } else {
                hide(item);
              }
          }
      }

      function onClickEvent(e) {
          console.log(e);
      }

      function Concepts() {
          this.onclick = function(e) {
              onClickEvent(e);
          }
          this.ontimeupdate = function(e) {
              onTimeUpdateEvent(e);
          }
      }

      return new Concepts();
  };
})( jQuery );
